   /* This program is free software. It comes without any warranty, to
    * the extent permitted by applicable law. You can redistribute it
    * and/or modify it under the terms of the Do What The Fuck You Want
    * To Public License, Version 2, as published by Sam Hocevar. See
    * http://www.wtfpl.net/ for more details. */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>



#define SUCCESS 0
#define FAILURE 1

#define bf_cmd_end 0 // 0
#define bf_buf_add 1 // >
#define bf_buf_mns 2 // <
#define bf_pnt_add 3 // +
#define bf_pnt_mns 4 // -
#define bf_loop_strt 5 // [
#define bf_loop_end 6 // ]
#define bf_std_in 7 // ,
#define bf_std_out 8 // .

#define FILESIZE 8192
#define BUFFERSIZE 30001



int main(int argc, char** argv){

    FILE *fp;
    fp = fopen("hello.txt", "r");

    
    short int *buffer = (short*)malloc(FILESIZE);
    unsigned int *cmd_buffer = (unsigned int*)malloc(BUFFERSIZE);
    memset(cmd_buffer, 0, BUFFERSIZE);
    memset(buffer, 0, FILESIZE);

    unsigned int *pt = cmd_buffer;
    short *bpt = buffer;
    unsigned int *save;
    int lp = 0;
    char o;

    while( (o = getc(fp)) != EOF && lp<FILESIZE){
        switch(o){

        case '>':
            buffer[lp] = bf_buf_add;
            break;
        case '<':
            buffer[lp] = bf_buf_mns;
            break;
        case '+':
            buffer[lp] = bf_pnt_add;
            break;
        case '-':
            buffer[lp] = bf_pnt_mns;
            break;
        case '[':
            buffer[lp] = bf_loop_strt;
            break;
        case ']':
            buffer[lp] = bf_loop_end;
            break;
        case ',':
            buffer[lp] = bf_std_in;
            break;
        case '.':
            buffer[lp] = bf_std_out;
            break;
        default:
            lp--;
            break;
        }
        lp++;
    }
    buffer[lp] = bf_cmd_end;
    lp = 0;
    for(int i = 0; buffer[i] != bf_cmd_end; i++){
        switch(buffer[i]){
        case 1:
            pt++;
            break;
        case 2:
            pt--;
            break;
        case 3:
            (*pt)++;
            break;
        case 4:
            (*pt)--;
            break;
        case 5:
            save = pt;
            lp = i;
            break;
        case 6:
            if(*save > 0){
                pt = save;
                i = lp;
            }
            break;
        case 7:
            *pt = (unsigned int)getc(stdin);
            break;
        case 8:
            printf("%c", *pt);
            break;

        }

    }
    return SUCCESS;
}

